package com.atguigu.guli.service.sms.service.impl;

import com.atguigu.guli.common.util.utils.FormUtils;
import com.atguigu.guli.common.util.utils.RandomUtils;
import com.atguigu.guli.service.base.consts.Keys;
import com.atguigu.guli.service.base.exception.GuliException;
import com.atguigu.guli.service.base.result.ResultCodeEnum;
import com.atguigu.guli.service.sms.service.SmsService;
import com.atguigu.guli.service.sms.util.HttpUtils;
import com.atguigu.guli.service.sms.util.SmsProperties;
import com.google.gson.Gson;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class SmsServiceImpl implements SmsService {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    SmsProperties smsProperties;
    @Override
    public void sendMsg(String mobile) {
        //1、检查手机号码格式:   正则表达式
        boolean b = FormUtils.isMobile(mobile);
        if(!b){
            //28006
            //28009
            throw new GuliException(ResultCodeEnum.LOGIN_PHONE_ERROR);
        }
        String codeKey = Keys.CODE_KEY_PREFIX+mobile;
        String codePlKey = Keys.CODE_PL_KEY_PREFIX+mobile;
        String codeCountKey = Keys.CODE_COUNT_KEY_PREFIX+mobile;
        //2、检查手机号码1分钟内是否获取过验证码
        if(redisTemplate.hasKey(codePlKey)){
            //28007
            throw new GuliException(ResultCodeEnum.SMS_SEND_ERROR_BUSINESS_LIMIT_CONTROL);
        }
        //3、检查手机号码24小时内获取验证码的次数是否超过5次
        Object countObj = redisTemplate.opsForValue().get(codeCountKey);
        if(countObj!=null){
            int i = Integer.parseInt(countObj.toString());
            if(i>=Keys.COUDE_COUNT_LIMIT){
                //28008
                throw new GuliException(ResultCodeEnum.SMS_SEND_ERROR_COUNT_LIMIT_CONTROL);
            }
        }
        //4、发送验证码
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + smsProperties.getAppcode()); //代表账户信息
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("mobile", mobile);
        String code = RandomUtils.getFourBitRandom();
        querys.put("param", "**code**:"+code+",**minute**:10");
        querys.put("smsSignId", smsProperties.getSmsSignId());
        querys.put("templateId",smsProperties.getTemplateId());
        Map<String, String> bodys = new HashMap<String, String>();
        try {
            HttpResponse response = HttpUtils.doPost(smsProperties.getHost(), smsProperties.getPath(),
                    smsProperties.getMethod(), headers, querys, bodys);
            Gson gson = new Gson();
            Map map = gson.fromJson(EntityUtils.toString(response.getEntity()), Map.class);
            String returnCode = map.get("code").toString();
            if(!"0".equals(returnCode)){
                throw new GuliException(ResultCodeEnum.SMS_SEND_ERROR);
            }
            //5、保存验证码10分钟[redis]

            redisTemplate.opsForValue().set(codeKey , code , 10 , TimeUnit.MINUTES);
            //更新当前手机号码获取验证码的频率次数
            redisTemplate.opsForValue().set(codePlKey , "12345234" , 1 , TimeUnit.MINUTES);
            //如果该手机号码第一次获取验证码，初始化一个24小时过期的键存它的次数
//            以后再次基础上+1
            Boolean hasKey = redisTemplate.hasKey(codeCountKey);
            if(hasKey){
                redisTemplate.opsForValue().increment(codeCountKey);
            }else{
                redisTemplate.opsForValue().set(codeCountKey , 1 , 24 , TimeUnit.HOURS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
